/*================================================================
*   Copyright (C) 2020 Sangfor Ltd. All rights reserved.
*   
*   文件名称：main.cpp
*   创 建 者：Ann
*   创建日期：2020年05月17日
*   描    述：
*
================================================================*/

#include "tcpsvr.hpp"
#include "SelectSvr.hpp"

#define CHECK_RET(p) if(p != true){return 0;}

int main(int argc, char* argv[])
{
    if(argc != 3)
    {
        printf("Start this process use in: ./tcpsvr [ip] [port]\n");
        return 0;
    }

    std::string ip = argv[1];
    uint16_t port = atoi(argv[2]);

    TcpServer listen_tcpsvr;
    CHECK_RET(listen_tcpsvr.CreateSock());
    CHECK_RET(listen_tcpsvr.Bind(ip, port));
    CHECK_RET(listen_tcpsvr.Listen(5));

    //创建select服务
    SelectSvr st;
    st.Add(listen_tcpsvr.GetFd());

    while(1)
    {
        //监控
        std::vector<TcpServer> vec;
        if(!st.SelectWait(&vec, 3000))
        {
            continue;
        }

        for(size_t i = 0; i < vec.size(); i++)
        {
            if(vec[i].GetFd() == listen_tcpsvr.GetFd())
            {
                //有连接
                TcpServer peerts;
                struct sockaddr_in peeraddr;
                if(!listen_tcpsvr.Accept(peerts, &peeraddr))
                {
                    printf("accept failed; try again\n");
                    continue;
                }

                printf("Have new connect: ip:%s port:%d\n", inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port));
                st.Add(peerts.GetFd());
            }
            else
            {
                printf("recv data from %d\n", vec[i].GetFd());
                std::string buf;
                if(!vec[i].Recv(buf))
                {
                    //接收失败，可能是对端已经关闭了连接，所以我们自己也将套接字描述符关闭掉
                    st.DeleteFd(vec[i].GetFd());
                    vec[i].Close();
                }

                printf("recv data %s from %d\n", buf.c_str(), vec[i].GetFd());
            }
        }
    }
    listen_tcpsvr.Close();
    return 0;
}
